//
//  NSObject+KVO.m
//  KVO
//
//  Created by 徐凯 on 2018/12/30.
//  Copyright © 2018 徐凯. All rights reserved.
//

#import "NSObject+KVO.h"
#import <objc/runtime.h>
#import <objc/message.h>
//static void *const objc = (void *)&objc;
@implementation Student  (KVO)
-(void)XK_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{
    NSString* oldClassName = NSStringFromClass([self class]);
    NSString* newClassName = [@"XKKVONotyfing_" stringByAppendingString:oldClassName];
    const char * newName = [newClassName UTF8String];
    Class newClass = objc_allocateClassPair([self class], newName, 0);
    //添加setter方法，相当于重写setter方法， "v@:i" 含义 @: id   : SEL     v : voidOC(消息发送机制),方法由两部分组成，方法编号@selector和方法实现(imp方法指针)，先找方法编号再得到方法的指针，再执行方法的代码块。
    class_addMethod(newClass,@selector(setAge:), (IMP)setAge, "v@:i");
    //注册新添加的这个类
    objc_registerClassPair(newClass);
    //修改被观察这的isa指针，isa指针指向Person类改成指向myclass这个类
     object_setClass(self, newClass);
    //将观察者的属性保存到当前类里面去
    objc_setAssociatedObject(self, (__bridge const void *)@"objc", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}
//相当于重写父类的方法
void setAge(id self, SEL _cmd, int age) {
    Class myClass = [self class];
    object_setClass(self, class_getSuperclass([self class]));
    //调用父类
   id (*msgSend) (id, SEL,...) = (void *)objc_msgSend;
    msgSend(self, @selector(setAge:),age);
    
    id observer = objc_getAssociatedObject(self, (__bridge const void *)@"objc");
    
     id (*msgSendObj) (id, SEL,id,...) = (void *)objc_msgSend;
    //通知观察
msgSendObj(observer,@selector(XK_observeValueForKeyPath:ofObject:change:context:),@"age",@"age",nil,nil);
    
    //改为子类
    object_setClass(self, myClass);
}

@end
